package com.ljt.yupictureddd.domain.space.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljt.yupictureddd.domain.space.entity.Space;
import com.ljt.yupictureddd.domain.space.entity.SpaceUser;
import com.ljt.yupictureddd.domain.space.service.SpaceDomainService;
import com.ljt.yupictureddd.domain.space.service.SpaceUserDomainService;
import com.ljt.yupictureddd.domain.space.valueobject.SpaceRoleEnums;
import com.ljt.yupictureddd.domain.user.entity.User;
import com.ljt.yupictureddd.domain.user.service.UserDomainService;
import com.ljt.yupictureddd.infrastracture.exception.BusinessException;
import com.ljt.yupictureddd.infrastracture.exception.ErrorCode;
import com.ljt.yupictureddd.infrastracture.exception.ThrowUtils;
import com.ljt.yupictureddd.infrastracture.mapper.SpaceUserMapper;
import com.ljt.yupictureddd.interfaces.dto.spaceuser.SpaceUserAddRequest;
import com.ljt.yupictureddd.interfaces.dto.spaceuser.SpaceUserQueryRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-01-02 20:07:15
 */
@Service
public class SpaceUserDomainServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser>
        implements SpaceUserDomainService {

    @Resource
    private UserDomainService userDomainService;

    @Resource
    @Lazy //解决circular bug //直接在循环♻的结束的那个类，找到对应字段加入lazy
    // ┌─────┐
    // |  spaceServiceImpl
    // ↑     ↓
    // |  spaceUserServiceImpl （在这个类里面找到spaceService加上@lazy）
    // └─────┘
    private SpaceDomainService spaceDomainService;

    @Override
    public long createSpaceUser(SpaceUserAddRequest spaceUserAddRequest) {
        // 参数校验
        ThrowUtils.throwIf(spaceUserAddRequest == null, ErrorCode.PARAMS_ERROR);
        SpaceUser spaceUser = new SpaceUser();
        BeanUtils.copyProperties(spaceUserAddRequest, spaceUser);
        validSpaceUser(spaceUser, true);
        // 数据库操作
        boolean result = this.save(spaceUser);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return spaceUser.getId();
    }

    @Override
    public void validSpaceUser(SpaceUser spaceUser, boolean add) {
        ThrowUtils.throwIf(spaceUser == null, ErrorCode.PARAMS_ERROR);
        // 创建时，空间 id 和用户 id 必填
        Long spaceId = spaceUser.getSpaceId();
        Long userId = spaceUser.getUserId();
        if (add) {
            ThrowUtils.throwIf(ObjectUtil.hasEmpty(spaceId, userId), ErrorCode.PARAMS_ERROR);
            User user = userDomainService.getById(userId);
            ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
            Space space = spaceDomainService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
        // 校验空间角色
        String spaceRole = spaceUser.getSpaceRole();
        SpaceRoleEnums spaceRoleEnum = SpaceRoleEnums.getEnumByValue(spaceRole);
        if (spaceRole != null && spaceRoleEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间角色不存在");
        }
    }


    @Override
    public QueryWrapper<SpaceUser> getQueryWrapper(SpaceUserQueryRequest spaceUserQueryRequest) {
        QueryWrapper<SpaceUser> queryWrapper = new QueryWrapper<>();
        if (spaceUserQueryRequest == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = spaceUserQueryRequest.getId();
        Long spaceId = spaceUserQueryRequest.getSpaceId();
        Long userId = spaceUserQueryRequest.getUserId();
        String spaceRole = spaceUserQueryRequest.getSpaceRole();
        queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "spaceId", spaceId);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceRole), "spaceRole", spaceRole);
        return queryWrapper;
    }
}

